Hough Transform


In [5]:
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import cv2

# convert to grayscale and smooth with a Gaussian
img = mpimg.imread('testimg.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
kernel_size = 5
blurred = cv2.GaussianBlur(gray_img, (kernel_size, kernel_size), 0)

# edge detect with Canny
low = 50
high = 150
edges = cv2.Canny(blurred, low, high)

# build lines with Hough transform
rho = 1
theta = np.pi/180
threshold = 1
min_line_length = 10
max_line_gap = 1
line_img = np.copy(img) * 0 # blank of same dim as our img

lines = cv2.HoughLinesP(edges, rho, theta, 
                        threshold,np.array([]), min_line_length, max_line_gap)
# draw!
for line in lines:
    for x1, y1, x2, y2 in line:
        cv2.line(line_img, (x1,y1), (x2,y2), (255,0,0), 10)

# colorized binary image
colorized = np.dstack((edges, edges, edges))

# draw the colorized lines
combined = cv2.addWeighted(colorized, 0.8, line_img, 1, 0)
plt.imshow(combined)
plt.show()


Hough transform combined with a polygonal mask

Notice that lines are more well-defined


In [65]:
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import cv2

# convert to grayscale and smooth with a Gaussian
img = mpimg.imread('testimg.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
kernel_size = 5
blurred = cv2.GaussianBlur(gray_img, (kernel_size, kernel_size), 0)

# edge detect with Canny
low = 50
high = 150
edges = cv2.Canny(blurred, low, high)

# build masked edge
mask = np.zeros_like(edges)
mask_ignored = 255

imshape = img.shape

# TODO turn these knobs until the mask selects the lane area
#def draw(n1, n2, n3, n4):    
vertices = np.array([[(275,imshape[0]),(650, 200), 
                      (imshape[1], 1000), 
                      (imshape[1],imshape[0])]], dtype=np.int32)
cv2.fillPoly(mask, vertices, mask_ignored)
masked_edges = cv2.bitwise_and(edges, mask)

# build lines with Hough transform
rho = 1
theta = np.pi/180
threshold = 1
min_line_length = 5
max_line_gap = 1
line_img = np.copy(img) * 0 # blank of same dim as our img

lines = cv2.HoughLinesP(masked_edges, rho, theta, 
                        threshold, np.array([]),
                        min_line_length, max_line_gap)
# draw!
for line in lines:
    for x1, y1, x2, y2 in line:
        cv2.line(line_img, (x1,y1), (x2,y2), (255,0,0), 10)

# colorized binary image
colorized = np.dstack((edges, edges, edges))

# draw the colorized lines
combined = cv2.addWeighted(colorized, 0.8, line_img, 1, 0)
plt.imshow(combined)
plt.show()


Good explanation of params from quiz answer:

Here's how I did it: I went with a low_threshold of 50 and high_threshold of 150 for Canny edge detection.

For region selection, I defined vertices = np.array([[(0,imshape[0]),(450, 290), (490, 290), (imshape[1],imshape[0])]], dtype=np.int32)

I chose parameters for my Hough space grid to be a rho of 2 pixels and theta of 1 degree (pi/180 radians). I chose a threshold of 15, meaning at least 15 points in image space need to be associated with each line segment. I imposed a min_line_length of 40 pixels, and max_line_gap of 20 pixels.